前段时间做爬虫,涉及到对图片验证码的破解,这里罗列一些常用的图像处理方法,都很简单并没用到什么复杂的算法,所以不涉及opencv,都是一些直接对rgb像素点的操作,很简单也很好理解,至于识别直接用的tesseract-ocr,也可以用svm。(ps:图片的像素值矩阵的原点在左上角,上边是x轴,左边是y轴)
1、灰度化和二值化,即把彩色图片经过灰度化和二值化变成只有黑白(只有0,1的矩阵)的数据,便于后续对图片的处理
public static BufferedImage grayImage(BufferedImage bufferedImage) throws Exception {
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
BufferedImage grayBufferedImage = new BufferedImage(width, height, bufferedImage.getType());
for (int i = 0; i < bufferedImage.getWidth(); i++) {
for (int j = 0; j < bufferedImage.getHeight(); j++) {
final int color = bufferedImage.getRGB(i, j);
final int r = (color >> 16) & 0xff;
final int g = (color >> 8) & 0xff;
final int b = color & 0xff;
int gray = (int) (0.3 * r + 0.59 * g + 0.11 * b);
int newPixel = colorToRGB(255, gray, gray, gray);
grayBufferedImage.setRGB(i, j, newPixel);
}
}
return grayBufferedImage;
}
/**
* 颜色分量转换为RGB值
*
* @param alpha
* @param red
* @param green
* @param blue
* @return
*/
private static int colorToRGB(int alpha, int red, int green, int blue) {
int newPixel = 0;
newPixel += alpha;
newPixel = newPixel > 8;
rgb[2] = (pixel & 0xff);
float avg = (rgb[0]+rgb[1]+rgb[2])/3;
zuobiao[x][y] = avg;
}
}
//这里是阈值,白底黑字还是黑底白字,大多数情况下建议白底黑字,后面都以白底黑字为例
double SW = 192;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
if (zuobiao[x][y] =5){
image.setRGB(x,y,white);
}
}
}
for(int x = 1; x < w-1; x++){
int y = h-1;
if(isBlack(image.getRGB(x, y))){
int size = 0;
if(isWhite(image.getRGB(x-1, y))){
size++;
}
if(isWhite(image.getRGB(x+1, y))){
size++;
}
if(isWhite(image.getRGB(x, y-1))){
size++;
}
if(isWhite(image.getRGB(x+1, y-1))){
size++;
}
if(isWhite(image.getRGB(x-1, y-1))){
size++;
}
if(size>=5){
image.setRGB(x,y,white);
}
}
}
for(int y = 1; y < h-1; y++){
int x = 0;
if(isBlack(image.getRGB(x, y))){
int size = 0;
if(isWhite(image.getRGB(x+1, y))){
size++;
}
if(isWhite(image.getRGB(x, y+1))){
size++;
}
if(isWhite(image.getRGB(x, y-1))){
size++;
}
if(isWhite(image.getRGB(x+1, y-1))){
size++;
}
if(isWhite(image.getRGB(x+1, y+1))){
size++;
}
if(size>=5){
image.setRGB(x,y,white);
}
}
}
for(int y = 1; y < h-1; y++){
int x = w - 1;
if(isBlack(image.getRGB(x, y))){
int size = 0;
if(isWhite(image.getRGB(x-1, y))){
size++;
}
if(isWhite(image.getRGB(x, y+1))){
size++;
}
if(isWhite(image.getRGB(x, y-1))){
size++;
}
//斜上下为空时,去掉此点
if(isWhite(image.getRGB(x-1, y+1))){
size++;
}
if(isWhite(image.getRGB(x-1, y-1))){
size++;
}
if(size>=5){
image.setRGB(x,y,white);
}
}
}
//降噪,以1个像素点为单位
for(int y = 1; y < h-1; y++){
for(int x = 1; x < w-1; x++){
if(isBlack(image.getRGB(x, y))){
int size = 0;
//上下左右均为空时,去掉此点
if(isWhite(image.getRGB(x-1, y))){
size++;
}
if(isWhite(image.getRGB(x+1, y))){
size++;
}
//上下均为空时,去掉此点
if(isWhite(image.getRGB(x, y+1))){
size++;
}
if(isWhite(image.getRGB(x, y-1))){
size++;
}
//斜上下为空时,去掉此点
if(isWhite(image.getRGB(x-1, y+1))){
size++;
}
if(isWhite(image.getRGB(x+1, y-1))){
size++;
}
if(isWhite(image.getRGB(x+1, y+1))){
size++;
}
if(isWhite(image.getRGB(x-1, y-1))){
size++;
}
if(size>=8){
image.setRGB(x,y,white);
}
}
}
}
return image;
}
public static boolean isBlack(int colorInt)
{
Color color = new Color(colorInt);
if (color.getRed() + color.getGreen() + color.getBlue() 300)
{
return true;
}
return false;
}
public static int isBlack(int colorInt, int whiteThreshold) {
final Color color = new Color(colorInt);
if (color.getRed() + color.getGreen() + color.getBlue() |